package com.gwtjs.icustom.controller.install;

import java.io.IOException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.gwtjs.icustom.construct.AppConstruct;
import com.gwtjs.icustom.construct.AppTypeConstruct;
import com.gwtjs.icustom.construct.ShellResultConstruct;
import com.gwtjs.icustom.entity.ResultWrapper;
import com.gwtjs.icustom.mapper.AppMapper;
import com.gwtjs.icustom.mapper.ServerHostMapper;
import com.gwtjs.icustom.pojo.App;
import com.gwtjs.icustom.pojo.ServerHost;
import com.gwtjs.icustom.utils.JScpUtil;
import com.gwtjs.icustom.utils.LinuxIPUtil;
import com.gwtjs.icustom.utils.ShellUtil;

@RestController
@RequestMapping("/install")
public class InstallToolController {

	private final static Logger logger = LoggerFactory.getLogger(InstallToolController.class);

	@Value("${app.work.home}")
	private String workHome;

	private final static String JDK_TAR_NAME = "jdk-8u371-linux-x64.tar.gz";
	
	@Autowired
	private AppMapper appMapper;
	@Autowired
	private ServerHostMapper serverHostMapper;

	/**
	 * <h2>自动安装工具</h2>
	 * <p>
	 * <ul>
	 * <ol>
	 * <li>yum源</li>
	 * <li>jdk1.8</li>
	 * <li>系统lib</li>
	 * </ol>
	 * </ul>
	 * </p>
	 * @throws Exception 
	 */
	@PutMapping("/autoStart")
	public ResultWrapper autoStart(@RequestBody ServerHost server) throws Exception {
		List<ServerHost> records = serverHostMapper.queryHostList();
		logger.info("\n开始自动安装...............\n");
		
		ResultWrapper result = this.installSystemTools(records);
		logger.info("\n安装系统工具到主机 ：{}", result);
		
		result = this.installJdk(records);
		logger.info("\n安装JDK到主机 ：{}", result);
		
		result = this.ntpServer(server);
		logger.info("\n安装NTP Server到主机 ：{}", result.getStatus());
		
		result = this.ntpClient(server);
		logger.info("\n安装NTP Client到主机 ：{}", result.getStatus());
		for (ServerHost host : records) {
			host.setIsNtpdClientFlag(1);
			if(host.getHostIp().equals(server.getHostIp())) {
				host.setIsNtpdFlag(1);
			}
		}

		return ResultWrapper.constructSuccessResult(records);
	}

	/**
	 * <h2>:安装系统工具</h2>
	 * <p>
	 * 安装wget、ntp、vim、tree、screen、lsof、net-tools等系统工具
	 * </p>
	 * <p>
	 * 安装ambari需要的libtirpc-devel、snappy-devel等系统依赖；
	 * </p>
	 * 
	 * @param u
	 * @return
	 */
	@PutMapping("/lib")
	public ResultWrapper installSystemTools(@RequestBody List<ServerHost> records) {
		String cmd = "ip addr";
		ShellUtil execute = null;
		String result = null;
		for (ServerHost host : records) {
			execute = new ShellUtil(host.getHostIp(), host.getAccount(), host.getPassword(), host.getHostPort());

			cmd = "yum clean all && yum makecache";
			result = execute.executeForResult(cmd);
			logger.info("\n清理yum缓存 \ncmd ：{}\nresult:{}\n", cmd, result);

			cmd = "yum -y install " + getLibName();
			result = execute.executeForResult(cmd);
			logger.info("\nyum安装系统工具 \ncmd ：{}\nresult:{}\n", cmd, result);

			cmd = "rpm -qa libtirpc-devel snappy-devel " + getLibName();
			result = execute.executeForResult(cmd);
			logger.info("\n验证重点库 \ncmd ：{}\nresult:{}\n", cmd, result);

			host.setIsSysLibFlag(1);
			serverHostMapper.updateLibStatus(host);

			execute.close();

		}
		return ResultWrapper.successResult();

	}

	/**
	 * <h2>:安装jdk</h2>
	 * <p>
	 * <ul>
	 * <ol>
	 * <li>将文件发送到主机/tmp目录下</li>
	 * <li>解压文件名为：/usr/java/jdk1.8.0</li>
	 * <li>创建软链接：/usr/java/{default,latest}</li>
	 * <li>解压文件名为：设置环境变量</li>
	 * </ol>
	 * </ul>
	 * </p>
	 * 
	 * @throws IOException
	 */
	@PutMapping("/jdk")
	public ResultWrapper installJdk(@RequestBody List<ServerHost> records) throws IOException {
		App app = null;
		String cmd = "ip addr";
		ShellUtil execute = null;
		String result = null;
		// jdk1.8.0_371

		final String remote = "/tmp";
		final String local = String.format("%s/app/%s", workHome, JDK_TAR_NAME);
		final String profileScript = String.format("%s/shell/profile.sh", workHome);

		for (ServerHost host : records) {
			app = new App();
			app.setAppIp(host.getHostIp());

			execute = new ShellUtil(host.getHostIp(), host.getAccount(), host.getPassword(), host.getHostPort());

			cmd = "java -version";
			result = execute.executeForResult(cmd);
			logger.info("\n安装jdk 脚本测试 0 \ncmd ：{} \nresult:{}\n", cmd, result);
			boolean javaFlag = result.contains(ShellResultConstruct.COMMON_NOT);
			// 如果包含了command not found
			if (javaFlag) {
				logger.info("\n ================\n:IP{}\n开始执行JDK安装......:\n================", host.getHostIp());
				// 将安装文件压缩包分发到集群各主机
				JScpUtil.upload(host, local, remote);

				cmd = String.format("tar -zxvf %s/%s -C /opt", remote, JDK_TAR_NAME);
				result = execute.executeForResult(cmd);
				logger.info("\n安装jdk 脚本测试 0 cmd ：{}", cmd);

				cmd = String.format("rm -rf %s/%s ", remote, JDK_TAR_NAME);
				result = execute.executeForResult(cmd);
				logger.info("\n安装jdk 脚本测试 0 cmd ：{}", cmd);

				cmd = "rm -rf /usr/java && mkdir -p /usr/java && mv /opt/jdk1.8.0_371 /usr/java/jdk1.8.0";
				result = execute.executeForResult(cmd);
				logger.info("\n安装jdk 脚本测试 0 cmd ：{}", cmd);

				cmd = getJdkLnScript();
				logger.info("\n安装jdk 脚本测试 0 cmd ：{}\n ", cmd);
				result = execute.executeForResult(cmd);
				logger.info("\n安装jdk 脚本测试  result:{}\n", cmd, result);

				JScpUtil.upload(host, profileScript, remote);
				cmd = "chmod 755 /tmp/profile.sh && /tmp/profile.sh";
				logger.info("\n安装jdk 脚本测试 0 cmd ：{}\n ", cmd);
				result = execute.executeForResult(cmd);

				JScpUtil.upload(host, profileScript, remote);
				cmd = "rm -rf /tmp/profile.sh";
				logger.info("\n安装jdk 脚本测试 0 cmd ：{}\n ", cmd);
				result = execute.executeForResult(cmd);

				execute.close();
			} else {
				logger.info("\n ================\nIP:{}\nJDK已经安装......:\n================", host.getHostIp());
			}

			host.setJdkFlag(1);
			serverHostMapper.updateLibStatus(host);

		}
		return ResultWrapper.successResult();

	}
	
	/**
	 * <h2>安装ntp server </h2>
	 * <P>
	 * <h2>配置ntpd主配置文件/etc/ntp.conf</h2>
	   <h2>直接使用修改好的文件替换</h2>
	 * </p>
	 * @throws Exception 
	 */
	@PutMapping("/ntp")
	public ResultWrapper ntpServer(@RequestBody ServerHost server) throws Exception {
		
		final String local=String.format("%s/config/ntp/ntp.conf.template",workHome);
		final String remote="/tmp/";
		ShellUtil execute = new ShellUtil(server.getHostIp(), server.getAccount(), server.getPassword(), server.getHostPort());
		
		//template发送到ntpd server主机
		JScpUtil.upload(server, local, remote);
		
		////拷贝文件为ntp.conf,替换template_ip为ntpd server ip
		String cmd = String.format("cd /tmp && \\cp -rf ntp.conf.template ntp.conf && %s", getSedIpScript(server.getHostIp()));
		logger.info("\nntpd server cp file \n cmd ：{} \n" , cmd);
		String result = execute.executeForResult(cmd);
		logger.info("\nresult:{}\n" , result);
		
		//将/tmp/ntp.conf 覆盖式复制到/etc目录，并且重启ntpd
		cmd = String.format("\\cp -rf /tmp/ntp.conf /etc/ && %s",getNtpServiceExecute());
		result = execute.executeForResult(cmd);
		logger.info("\nntpd server start \ncmd ：{}\nresult:{}\n" , cmd,result);
		
		//清理/tmp/ntp.conf
		cmd = "rm -rf /tmp/ntp.conf";
		result = execute.executeForResult(cmd);
		logger.info("\nntpd server start \ncmd ：{}\nresult:{}\n" , cmd,result);
		
		App app = new App();
		app.setAppIp(server.getHostIp());
		app.setAppName(AppConstruct.NTPD_SERVER);
		app.setAppType(AppTypeConstruct.SYSTEM_TOOL);
		
		Integer appCount = appMapper.queryByNameAndIpCount(app);
		logger.info("\n httpd应用统计： {}\n" , appCount);
		if(!(appCount<1)) {
			appMapper.deleteApp(app);
		}
		
		appMapper.addApp(app);
		
		server.setIsNtpdFlag(1);
		serverHostMapper.updateLibStatus(server);
		
		return ResultWrapper.successResult();

	}
	
	/**
	 * <h2>安装ntp client </h2>
	 * <P>
	 * <h2>配置ntpd主配置文件/etc/ntp.conf</h2>
		<h2>客户端：</h2>
		#server 0.centos.pool.ntp.org上增加server server1并且注释掉所有server xxx 
		<h2>#做一个计划任务（从节点）</h2>
			<code>crontab -e
			00 * /3 * * * /usr/sbin/ntpdate  server1 >> /root/ntpdate.log 2>&1</code>
			<p>注意* /3蹭没有空格</p>
			<h2>所有子节点ntp加入开机启动</h2>
			<code>systemctl start ntpd  && systemctl enable ntpd.service && systemctl status ntpd.service</code>
			<h2>#每个从节点，从master节点同步时间</h2>
			<code>ntpdate -u server1 </code>
	 * </p>
	 * @throws Exception 
	 */
	@PutMapping("/ntp/client")
	public ResultWrapper ntpClient(@RequestBody ServerHost ntpServer) throws Exception {
		final String local="config/ntp/client/ntp.conf";
		final String remote="/tmp/";
		String cmd = "ip addr";
		String result = "";
		ShellUtil execute = null;
		
		//连接CD主机复制和替换模板
		String localIp = LinuxIPUtil.getLinuxLocalIp();
		logger.info("\n ntp => client linux local IP:{}\n",localIp);
		ServerHost localHost = serverHostMapper.queryHostByIp(localIp);
		logger.info("\n ntp => client ServerHost:{}\n",localHost);
		execute = new ShellUtil(localHost.getHostIp(), localHost.getAccount(), localHost.getPassword(), localHost.getHostPort());
		
		cmd = String.format("cd %s/config/ntp/client/ && \\cp -rf ntp.conf.template ntp.conf && %s",workHome, getSedIpScript(ntpServer.getHostIp()));
		result = execute.executeForResult(cmd);
		logger.info("\nntpd client cmd ：{} \n result:{}\n" , cmd,result);
		
		List<ServerHost> records=serverHostMapper.queryHostList();
		//拷贝文件为ntp.conf,替换template_ip为ntpd server ip, 发送到ntpd server主机
		for (ServerHost host : records) {
			JScpUtil.upload(host, local, remote);
			
			execute = new ShellUtil(host.getHostIp(), host.getAccount(), host.getPassword(), host.getHostPort());
			
			//\cp替换方式复制，重启ntp
			cmd = String.format("\\cp -rf /tmp/ntp.conf /etc/ && %s",getNtpServiceExecute());
			result = execute.executeForResult(cmd);
			logger.info("\nntpd client cmd ：{} \n result:{}\n" , cmd,result);
			
			cmd = String.format("echo '00 */3 * * * /usr/sbin/ntpdate %s >> /root/ntpdate.log 2>&1' > /var/spool/cron/%s && crontab -l",ntpServer.getHostIp(), host.getAccount());
			result = execute.executeForResult(cmd);
			logger.info("\nntpd client cmd ：{} \nresult:{}\n" , cmd,result);
			
			//清理/tmp/ntp.conf
			cmd = "rm -rf /tmp/ntp.conf";
			result = execute.executeForResult(cmd);
			logger.info("\nntpd client cmd ：{} \nresult:{}\n" , cmd,result);
			
			execute.close();
			
			host.setIsNtpdClientFlag(1);
			serverHostMapper.updateLibStatus(host);
			
		}
		
		return ResultWrapper.successResult();

	}
	/**
	 * <h2>系统工具名称</h2>
	 */
	private String getLibName() {
		String result = "vim psmisc ntp ntpdate wget git rsync gcc tree screen lsof net-tools zip unzip ";
		result += "zlib-devel bzip2-devel openssl-devel xz-libs redhat-lsb ";
		result += "python-devel python-kerberos snappy snappy-devel libtirpc libtirpc-devel nc rpcbind";
		return result;
	}

	/**
	 * <h2>拼接jdk 安装 shell指令</h2>
	 * 
	 * @return
	 */
	private String getJdkLnScript() {
		StringBuffer buff = new StringBuffer();
		buff.append("ln -s /usr/java/jdk1.8.0/ /usr/java/latest && ");
		buff.append("ln -s /usr/java/latest /usr/java/default && ");

		buff.append("ln -s /usr/java/latest/bin/java /usr/bin/ && ");
		buff.append("ln -s /usr/java/latest/bin/jps /usr/bin/ \n");

		return buff.toString();
	}
	
	/**替换模板中的IP为ntpd服务器IP*/
	private String getSedIpScript(final String hostIp) {
		return String.format("sed -i 's/template_ip/%s/g' ntp.conf", hostIp);
	}
	
	/**启动服务查看服务状态*/
	private String getNtpServiceExecute() {
		return "systemctl restart ntpd.service && systemctl enable ntpd.service && systemctl status ntpd.service";
	}
}
